#pragma once

#include <windows.h>

/** 
 * \ingroup ti6
 *
 * \brief
 * The Image class is used by (allmost) all image operations. The class contains
 * methods to request and change the bitmap data. By using the operator []
 * overloads, instances of the Image class can be used as a two-dimenstional
 * array (the Row class exists to support this feature).
 * The Image class is not the owner of the bitmap data (it's the DIB class).
 * In fact, it is just a description of the data to change and serves as a
 * layer between the operation and the DIB class. This fact can be ignored
 * while implementing the operations. For an image operation, the Image class
 * is just what it's name suggest: an image.
 *
 * Copyright (c) Academie voor ICT en Media 2007 - 2008
 */
class Image
{
public:
	//Windows stores the color channels in BGR order.
	enum Channel
	{
		BLUE = 0,
		GREEN = 1,
		RED = 2
	};

	/** 
	 * \ingroup ti6
	 *
	 * \brief
	 * A single row in the image. Instances of this class can be used to
	 * manipulate the pixels in this row.
	 *
	 * Copyright (c) Academie voor ICT en Media 2007 - 2008
	 */
	class Row
	{
	public:
		/**
		 \brief
		 Construct a Row instance. The data parameter must point to the
		 first pixel in the row.
		 
		 \param *data The raw bitmap data, starting at the requested row.
		 */
		Row( unsigned char *data )
			{ _data = data; }

		/**
		 \brief
		 Get a pixel (the specified column, within this row).
		 
		 \param col The column.
		 \return A pointer to the pixel. A pixel is an array with a
		   unsigned char for each channel(color).
		 */
		inline unsigned char* operator []( unsigned int col )
			{ return _data + 3 * col; }
	private:
		/**
		 Raw bitmap data. Starting at the beginning of a row.
		 */
		unsigned char *_data;
	};

	/**
	 \brief
	 Assignment operator. This function copies the bitmap data of img
	 to this instance. This requires both instances to have the same
	 size.
	 
	 \param &img The image to copy.
	 \return This instance.
	 */
	Image& operator =( const Image &img );

	/**
	 \brief
	 Get a specific row within this image.
	 
	 \param row The number of the row.
	 \return An Row instance, which represents the requested row.
	 */
	inline Row operator []( unsigned int row )
		{ return Row( _data + row * _bytesPerRow ); }

	/**
	 \brief
	 Get the raw bitmap data. This is an array of pixels and each pixel
	 is an array with the values for each channel. There may be some
	 unused bytes at the end of each row. To get the length of a row
	 in bytes, use bytesPerRow().\n
	 The raw bitmap data can be used for manipulating the image, but the
	 most usual way to do this is by operator []. This function can be
	 used when the raw data is required or when optimizing for speed.
	 
	 \return A pointer to raw bitmap data.
	 */
	inline unsigned char* data()
		{ return _data; }

	/**
	 \brief
	 Get the size of a row, in bytes. This value is at least equal to
	 width() * 3 (the number of channels). It can be larger due to padding
	 (rounding the value up to the nearest double word) or because the
	 image description does not reflect the full width of the DIB.
	 
	 \return The number of bytes per row.
	 */
	inline unsigned int bytesPerRow() const
		{ return _bytesPerRow; }

	/**
	 \brief
	 Get the width of the image, in pixels.
	 
	 \return The width of the image.
	 */
	unsigned int width() const;

	/**
	 \brief
	 Get the height of the image, in pixels.
	 
	 \return The height of the image.
	 */
	unsigned int height() const;
private:
	/**
	 \brief
	 Create an image instance for the specified data. This function
	 will not validate all input. It is declared private because it
	 is intended to be used only by DIB. To get an Image, use
	 DIB::getImage().
	 
	 \param bytesPerRow The number of bytes in each row.
	 \param *data Pointer to raw data, starting at the first pixel
	   within this image.
	 \param size The size of the image, which is equal to or smaller
	   than the size of the DIB.
	 */
	Image( unsigned int bytesPerRow, unsigned char *data, SIZE size );

	/**
	 The number of bytes per row.
	 */
	unsigned int _bytesPerRow;

	/**
	 Pointer to raw bitmap data.
	 */
	unsigned char *_data;

	/**
	 The size of the image.
	 */
	SIZE _size;

	/**
	 The DIB class is allowed to create Image instances. An Image
	 is, in fact, a decription of a part of a DIB.
	 */
	friend class DIB;
};
